package com.youbug.system.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.youbug.common.vo.QueryVo;
import com.youbug.system.entity.SysLog;
import com.youbug.system.entity.SysLogError;
import com.youbug.system.entity.SysLogInfo;
import com.youbug.system.service.SysLogService;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;


@Service
public class SysLogServiceImpl implements SysLogService {

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    public IPage<SysLog> getSysLogs(QueryVo<SysLog> sysLogQueryVo) {

        NativeSearchQueryBuilder searchQueryBuilder = new NativeSearchQueryBuilder();

        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        SysLog sysLog = sysLogQueryVo.getPayload();

        Class logType = SysLogError.class;

        if(StringUtils.hasText(sysLog.getLevel())){

            MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("level", sysLog.getLevel());

            searchQueryBuilder.withQuery(matchQuery);

            if("INFO".equals(sysLog.getLevel())){
                logType = SysLogInfo.class;
            }
            boolQueryBuilder.must(matchQuery);
        }

        if(StringUtils.hasText(sysLog.getTrace())){
            MatchQueryBuilder trace = QueryBuilders.matchQuery("trace", sysLog.getTrace());

            boolQueryBuilder.must(trace);
        }

        if(!ObjectUtils.isEmpty((sysLog.getStartTime()))){

            RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("@timestamp").from(sysLog.getStartTime()).timeZone("UTC+8").to(sysLog.getEndTime());

            boolQueryBuilder.must(rangeQueryBuilder);
        }

        searchQueryBuilder.withPageable(PageRequest.of(sysLogQueryVo.getCurrentPage().intValue() - 1, sysLogQueryVo.getPageSize().intValue()));

        FieldSortBuilder order = SortBuilders.fieldSort("@timestamp").order(SortOrder.DESC);

        searchQueryBuilder.withSort(order);

        searchQueryBuilder.withQuery(boolQueryBuilder);

        NativeSearchQuery query = searchQueryBuilder.build();

        SearchHits<SysLog> search = elasticsearchRestTemplate.search(query, logType);

        long totalHits = search.getTotalHits();

        List<SysLog> collect = search.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());

        Page<SysLog> page = new Page<>();

        page.setCurrent(sysLogQueryVo.getCurrentPage());
        page.setRecords(collect);
        page.setSize(sysLogQueryVo.getPageSize());
        page.setTotal(totalHits);

        return page;

    }
}


